package com.yc.anno;

/**
 * java.lang.reflect java反射包
 */
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Date;

public class Demo1 {

    public static void main(String[] args) throws Exception {
        // 反射操作从 类对象 开始 class
        /**
         *  获取类对象的方式
         *  1. 类.class          Demo1.class
         *  2. 对象.getClass()   new Demo1().getClass();
         *  3. Class.forName("类路径");  返回 类对象
         */

        test(true);
        test("true");
        test(1234);

        test1(SubPerson.class);
    }

    public static void test(Object t){
        /**
         *  获取t的类型
         */
        System.out.println(t.getClass().getName()); // 类路径
        System.out.println(t.getClass().getSimpleName()); // 类名(无包名)
    }

    public static void test1(Class cls) throws Exception{

        /**
         * getXXX() 如不带 Declared 那么返回 共有元素(属性,方法...)
         *             带 Declared 那么返回该类定义的元素
         */
        System.out.println("======== 不带 Declared===========");
        //Method method = cls.getMethod("???");
        Method[] methods = cls.getMethods();
        for(Method m : methods){
            System.out.println(m);
        }

        System.out.println("======== 带 Declared===========");
        //method = cls.getDeclaredMethod("???");
        methods = cls.getDeclaredMethods();

        for(Method m : methods){
            System.out.println(m);
        }

        // 输出所有定义的属性
        System.out.println("======== 带 Declared===========");
        Field[] fs = cls.getDeclaredFields();
        for(Field f : fs){
            System.out.println(f);
        }
        System.out.println("======== 不带 Declared===========");
        // 输出所有共有的属性
        fs = cls.getFields();
        for(Field f : fs){
            System.out.println(f);
        }
        System.out.println("======== 执行方法 ===========");
        // 通过方式创建对象
        SubPerson subPerson = (SubPerson) cls.newInstance(); // ==> new SubPerson();

        // 如果反射获取属性值
        Field f = cls.getDeclaredField("birthday");
        // 非共有属性要访问或获取属性值, 需要设置强制可见性
        f.setAccessible(true);
        // 通过属性对象设置
        f.set(subPerson, new Date());

        // 通过方法对象取值
        Method m = cls.getDeclaredMethod("getBirthday",
                String.class, char.class);
        m.setAccessible(true);
        // 动态执行方法
        Date date = (Date) m.invoke(subPerson,"随便", '0');
        System.out.println("-----------" + date);
    }

}


/**
 * birthday 是定义的元素, age,name,gender 不是定义的元素
 */

class SubPerson extends Person {
    private Date birthday;

    private Date getBirthday(int a) {
        return birthday;
    }

    private Date getBirthday(String a) {
        return birthday;
    }

    private Date getBirthday(String a, char b) {
        return birthday;
    }
}

/**
 * name,age,gender 全部是定义的元素 Declared
 */
class Person {
    private String name;
    protected int age;
    public char gender;

    private String getName() {
        return name;
    }

    private void setName(String name) {
        this.name = name;
    }

    protected int getAge() {
        return age;
    }

    protected void setAge(int age) {
        this.age = age;
    }

    public char getGender() {
        return gender;
    }

    public void setGender(char gender) {
        this.gender = gender;
    }
}


